#include <curl/curl.h>
#include <tinyxml.h>

#include "AppFlickRModel.h"

#include "FlickR_Img.h"

#define URL "http://query.yahooapis.com/v1/public/yql?q="
#define TMP_FILE_NAME "tmp/flickr.xml"

FILE* temp;

size_t write_data(void * ptr, size_t size, size_t nmeb, void *stream){
  return fwrite(ptr,size,nmeb,temp);
}



AppFlickRModel::AppFlickRModel(){

}

void AppFlickRModel::loadImgFromId(std::string user_id){
  temp = fopen(TMP_FILE_NAME,"w+");
  std::string request("select%20*%20from%20flickr.people.publicphotos%20where%20user_id=\""+user_id+"\";");

  std::string final_url(URL+request);
  
  /* process the file download form HTTP */
  {
    CURL* curl;
    curl = curl_easy_init();
    curl_easy_setopt(curl,CURLOPT_URL,final_url.c_str());
    curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_data);
    curl_easy_perform(curl);
    curl_easy_cleanup(curl);
  }
  fclose(temp);

  /* parse the XML downloaded file */
  {
    TiXmlDocument doc(TMP_FILE_NAME);
    doc.LoadFile();

    // TiXmlHandle hDoc(&doc);
    TiXmlHandle hRoot(&doc);
    {
      TiXmlElement* pResultsNode =
	hRoot.FirstChild("query").FirstChild( "results" ).FirstChild().Element();
      for( ; 
	   pResultsNode; 
	   pResultsNode = pResultsNode->NextSiblingElement()) {
	std::string* farm_str;
	int farm;
	std::string* id;
	std::string* isFamily_str;
	int isFamily;
	std::string* isFriend_str;
	int isFriend;
	std::string* isPublic_str;
	int isPublic;
	std::string* owner;
	std::string* secret;
	std::string* server_str;
	int server;
	std::string* title;
	
	farm_str = new std::string(pResultsNode->Attribute("farm"));
	farm = atoi(farm_str->c_str());
	
	isFamily_str = new std::string(pResultsNode->Attribute("isfamily"));
	isFamily = atoi(isFamily_str->c_str());

	isFriend_str = new std::string(pResultsNode->Attribute("isfriend"));
	isFriend = atoi(isFriend_str->c_str());

	isPublic_str = new std::string(pResultsNode->Attribute("ispublic"));
	isPublic = atoi(isPublic_str->c_str());

	owner = new std::string(pResultsNode->Attribute("owner"));
	id = new std::string(pResultsNode->Attribute("id"));
		
	secret = new std::string(pResultsNode->Attribute("secret"));

	server_str = new std::string(pResultsNode->Attribute("server"));
	server = atoi(server_str->c_str());

	title = new std::string(pResultsNode->Attribute("title"));
	
	FlickR_Img img(farm,*id,(isFamily == 1),
		       (isPublic == 1),(isFriend == 1), *owner, *secret,
		       server, *title);
	
	_photo.push_back(img);
	delete farm_str;
	delete isFamily_str;
	delete isFriend_str;
	delete isPublic_str;
	delete server_str;
	delete id;
	delete owner;
	delete secret;
	delete title;
      }    
    }
  } 
 
}

std::list<FlickR_Img> AppFlickRModel::getPictures(){
  return _photo;
}

std::list<std::string> AppFlickRModel::cacheFiles(int size){
  std::list<std::string> ret;
  int count = 0;
  std::cout << "loading cache [1]:";
  for(std::list<FlickR_Img>::iterator it = _photo.begin();
      (it != _photo.end()) && (count < size);
      it++,++count){
    ret.push_back( it->getSmallPicture_str() );
    std::cout << ((float)count/(float)size)*100. << "%...";
    fflush(stdout);
  }
  std::cout << std::endl;

  return ret;
}

std::list<std::string> AppFlickRModel::cacheLargeFiles(int size){
  std::list<std::string> ret;
  int count = 0;
  std::cout << "loading cache [2]:";
  for(std::list<FlickR_Img>::iterator it = _photo.begin();
      (it != _photo.end()) && (count < size);
      it++,++count){
    ret.push_back( it->getLargePicture_str() );
    std::cout << ((float)count/(float)size)*100. << "%...";
    fflush(stdout);
  }
  std::cout << std::endl;

  return ret;
}

FlickR_Img AppFlickRModel::frontPicture(){
  return _photo.front();
}

AppFlickRModel::~AppFlickRModel() {

}
